# -*- coding: utf-8 -*-

import base64
import hashlib
import requests
import json
import logging

from com.maycur.gateway.common.base_entity import EnvInfo, ApiOrgInfo, MaycurWebUser
from com.maycur.utils import TimeUtils


class LoginUtils:

    def openapi_login(self, app_code, app_secret, env_info: EnvInfo):
        login_url = f'{env_info.value.app_host}/api/openapi/auth/login'
        headers = self._get_headers()

        timestamp = TimeUtils.current_timestamp()
        encrypted_secret = self._sha256_hex(app_code, app_secret, timestamp)

        body_data = {
            "secret": encrypted_secret,
            "appCode": app_code,
            "timestamp": timestamp
        }
        json_body = json.dumps(body_data)
        res = requests.post(login_url, data=json_body, headers=headers)
        print('login res is as follows:')
        print(res)
        if res.status_code == 429:
            print(f'res headers: {res.headers}')
        json_content = json.loads(res.content)
        if ('status' in json_content and json_content['status'] == 200) or 'ACK' == json_content['code']:
            res_data = json_content['data']
            ent_code = res_data['entCode']
            token_id = res_data['tokenId']

            print(f'entCode = {ent_code}')
            print(f'token_id: \n{token_id}')
            return [ent_code, token_id]
        else:
            print('Login failed')
            print(json_body)
            print(json_content)

    def webapi_login(self, env_info: EnvInfo, user_info: MaycurWebUser) -> ApiOrgInfo:
        auth_host = env_info.value.auth_host
        # 步骤1，获取Boss操作对应的token
        boss_token_url = f'{auth_host}/backend/sign-in/v2/authorize'
        boss_token_body = {
            "account": str(user_info.phone_number),
            "password": str(user_info.password),
            "deviceId": ""
        }
        boss_token_res = requests.post(boss_token_url, data=json.dumps(boss_token_body), headers=self._get_headers())
        if boss_token_res.status_code != 200:
            logging.error(f'web api login failed, phone number is {user_info.phone_number}')
            return
        boss_token = json.loads(boss_token_res.text)['data']

        # 步骤2，选择公司登录
        all_enterprise_url = f'{auth_host}/backend/sign-in/v2/enterprises'
        all_enterprise_res = requests.post(all_enterprise_url, headers=self._get_headers_with_authorization(boss_token))
        if all_enterprise_res.status_code != 200:
            print(all_enterprise_res.text)
            logging.error(f'web api login failed to list all enterprises')
            return
        all_enterprise = json.loads(all_enterprise_res.text)['data']
        select_enterprise = None
        for enterprise_item in all_enterprise:
            ent_code_item = enterprise_item['code']
            if user_info.default_ent_code is not None:
                if user_info.default_ent_code == ent_code_item:
                    select_enterprise = enterprise_item
                    break
            else:
                select_enterprise = enterprise_item
                break

        select_enterprise_url = f'{auth_host}/backend/sign-in/v2/enterprise/select'
        select_enterprise_body = {
            "code": select_enterprise['code'],
            "name": select_enterprise['name'],
            "productLine": select_enterprise['productLine']
        }
        select_ent_headers = self._get_headers_with_authorization(boss_token)
        res = requests.post(select_enterprise_url, data=json.dumps(select_enterprise_body), headers=select_ent_headers)
        if res.status_code != 200:
            logging.error(f'web api login failed to select enterprise')
            return

        # 步骤3，redirect并解析应用token
        redirect_url = f'{auth_host}/backend/sign-in/v2/redirect'
        redirect_headers = self._get_headers_with_authorization(boss_token)
        redirect_res = requests.post(redirect_url, data=json.dumps({}), headers=redirect_headers)
        if redirect_res.status_code != 200:
            logging.error(f'web api login failed to redirect')
            return

        p_param = json.loads(redirect_res.text)['data']['p']
        token_id = json.loads(base64.b64decode(p_param))['accessToken']

        api_org_info = ApiOrgInfo()
        api_org_info.select_ent_code = select_enterprise['code']
        api_org_info.token_id = token_id
        return api_org_info

    @staticmethod
    def _get_headers():
        return {"content-type": "application/json"}

    def _get_headers_with_authorization(self, boss_token):
        headers = self._get_headers()
        headers['authorization'] = boss_token
        return headers

    @staticmethod
    def _sha256_hex(app_code, app_secret, timestamp):
        data = f'{app_secret}:{app_code}:{timestamp}'
        sha256 = hashlib.sha256()
        sha256.update(data.encode())
        return sha256.hexdigest()
